// File Locations.h
//
// Purpose: Contains the states for the locations in the game
//
// Author : Bryson King (edited)
// Original Code Provided by: Mat Buckland 2002 (fup@ai-junkie.com)
// Date : 19 March 2013
// --------------------------------------------------------------
#ifndef LOCATIONS_H
#define LOCATIONS_H

#include "AbstractLocation.h"
#include "IPerson.h"
#include "UserInterface.h"
#include "Item.h"
#include "GenericPerson.h"
#include "InterfaceStructures.h"
#include "Telegram.h"

//------------------------------------------------------------------------
//	BoatOutsideShip
//  This location is only applicable to the terrorists prior to boarding
//	the ship
//		Fore:	N/A
//		Aft:	N/A
//		Port:	N/A
//		Stbd:	N/A
//		Up:		USS Enterprise Elevator 1 (Hangar Deck)
//		Down:	N/A
//------------------------------------------------------------------------
class BoatOutsideShip : public CLocation
{
private:
	BoatOutsideShip();
	//copy ctor and assignment should be private
	BoatOutsideShip(const BoatOutsideShip&);
	BoatOutsideShip& operator=(const BoatOutsideShip&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;
	
public:
	//this is a singleton
	static BoatOutsideShip* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	EDivBerthing
//	This location is the starting point of the player and has the player
//	starting in his rack with the option to look around to find things
//		Fore:	N/A
//		Aft:	N/A
//		Port:	Entrance to 2nd Deck Part 1
//		Stbd:	Blocked by debris
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class EDivBerthing : public CLocation
{
private:
	EDivBerthing();
	//copy ctor and assignment should be private
	EDivBerthing(const EDivBerthing&);
	EDivBerthing& operator=(const EDivBerthing&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static EDivBerthing* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	SecondDeckPart1
//	This location is the place the player exits to after leaving berthing.
//	Has no option of finding anything here.
//		Fore:	Aft Mess Deck
//		Aft:	#4 Diesel Space (Upper Section)
//		Port:	N/A
//		Stbd:	E-Division Berthing
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class SecondDeckPart1 : public CLocation
{
private:
	SecondDeckPart1();
	//copy ctor and assignment should be private
	SecondDeckPart1(const SecondDeckPart1&);
	SecondDeckPart1& operator=(const SecondDeckPart1&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static SecondDeckPart1* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	AftMessDeck
//	This location is the mess deck on the aft end of the ship. There are
//	numerous tables with left-over food on them. There is nothing else
//	of interest here.
//		Fore:	Aft Bomb Transfer Area
//		Aft:	2nd Deck Part 1
//		Port:	N/A
//		Stbd:	N/A
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class AftMessDeck : public CLocation
{
private:
	AftMessDeck();
	//copy ctor and assignment should be private
	AftMessDeck(const AftMessDeck&);
	AftMessDeck& operator=(const AftMessDeck&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static AftMessDeck* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	AftBombXferArea
//	This location is the area where aircraft weapons are transferred. There
//	are numerous security personnel standing around holding M-16's and
//	other personnel moving aircraft weaponry around.
//		Fore:	N/A
//		Aft:	Aft Mess Deck
//		Port:	Ladderwell on Port side of ship
//		Stbd:	Ladderwell on Stbd side of ship
//		Up:		Weapons Transfer Elevator (once opened)
//		Down:	Weapons Transfer Elevator (once opened)
//------------------------------------------------------------------------
class AftBombXferArea : public CLocation
{
private:
	AftBombXferArea();
	//copy ctor and assignment should be private
	AftBombXferArea(const AftBombXferArea&);
	AftBombXferArea& operator=(const AftBombXferArea&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static AftBombXferArea* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	PropulsionBlock
//	This location is the area of the ship that covers the propulsion
//	plants and has numerous ellison doors to operate and hide in
//		Fore:	2nd Deck Part 2
//		Aft:	Aft Bomb Transfer Area
//		Port:	N/A
//		Stbd:	N/A
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class PropulsionBlock : public CLocation
{
private:
	PropulsionBlock();
	//copy ctor and assignment should be private
	PropulsionBlock(const PropulsionBlock&);
	PropulsionBlock& operator=(const PropulsionBlock&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static PropulsionBlock* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	SecondDeckPart2
//	This location is the second passageway through the 2nd Deck that
//	connects to the Forward Mess Deck, the E-Division Office, and Medical
//		Fore:	Forward Mess Deck
//		Aft:	Propulsion Block
//		Port:	Second Deck Part 2 Port (E-Division Office)
//		Stbd:	Second Deck Part 2 Stbd (Medical)
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class SecondDeckPart2 : public CLocation
{
private:
	SecondDeckPart2();
	//copy ctor and assignment should be private
	SecondDeckPart2(const SecondDeckPart2&);
	SecondDeckPart2& operator=(const SecondDeckPart2&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static SecondDeckPart2* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	EDivisionOffice
//	This location is the E-Division office
//		Fore:	N/A
//		Aft:	N/A
//		Port:	N/A
//		Stbd:	Second Deck Part 2
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class EDivisionOffice : public CLocation
{
private:
	EDivisionOffice();
	//copy ctor and assignment should be private
	EDivisionOffice(const EDivisionOffice&);
	EDivisionOffice& operator=(const EDivisionOffice&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static EDivisionOffice* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	MedicalOffice
//	This location is Medical
//		Fore:	N/A
//		Aft:	N/A
//		Port:	2nd Deck Part 2
//		Stbd:	N/A
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class MedicalOffice : public CLocation
{
private:
	MedicalOffice();
	//copy ctor and assignment should be private
	MedicalOffice(const MedicalOffice&);
	MedicalOffice& operator=(const MedicalOffice&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static MedicalOffice* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	FwdMessDeck
//	This location is the mess deck of the ship on the forward end of the
//	2nd deck
//		Fore:	Forward Bomb Transfer Area
//		Aft:	Second Deck Part 2
//		Port:	N/A
//		Stbd:	N/A
//		Up:		N/A
//		Down:	N/A
//------------------------------------------------------------------------
class FwdMessDeck : public CLocation
{
private:
	FwdMessDeck();
	//copy ctor and assignment should be private
	FwdMessDeck(const FwdMessDeck&);
	FwdMessDeck& operator=(const FwdMessDeck&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static FwdMessDeck* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	FwdBombXferArea
//	This location is the forward portion of the ship where bombs are
//	transferred and such
//		Fore:	N/A
//		Aft:	Forward Mess Deck
//		Port:	N/A
//		Stbd:	N/A
//		Up:		Hanger Deck Forward End
//		Down:	N/A
//------------------------------------------------------------------------
class FwdBombXferArea : public CLocation
{
private:
	FwdBombXferArea();
	//copy ctor and assignment should be private
	FwdBombXferArea(const FwdBombXferArea&);
	FwdBombXferArea& operator=(const FwdBombXferArea&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static FwdBombXferArea* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	HangarBayPart1
//	This location is the forward portion of the hangar bay and houses
//	Elevator #1
//		Fore:	N/A
//		Aft:	Hargar Bay Part 2
//		Port:	N/A
//		Stbd:	Elevator #1
//		Up:		N/A
//		Down:	Forward Bomb Transfer Area
//------------------------------------------------------------------------
class HangarBayPart1 : public CLocation
{
private:
	HangarBayPart1();
	//copy ctor and assignment should be private
	HangarBayPart1(const HangarBayPart1&);
	HangarBayPart1& operator=(const HangarBayPart1&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static HangarBayPart1* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

//------------------------------------------------------------------------
//	Elevator1
//	This location is the forward-most aircraft elevator on the ship
//		Fore:	N/A
//		Aft:	N/A
//		Port:	Hangar Deck Part 1
//		Stbd:	N/A
//		Up:		N/A
//		Down:	Boat Outside the Ship (Terrorist Boat)
//------------------------------------------------------------------------
class Elevator1 : public CLocation
{
private:
	Elevator1();
	//copy ctor and assignment should be private
	Elevator1(const Elevator1&);
	Elevator1& operator=(const Elevator1&);
 
	user_input_options m_sUserOptions;
	CItems m_oItems;

public:
	//this is a singleton
	static Elevator1* Instance();
	virtual void Enter(IPerson* entity);
	virtual void Execute(IPerson* entity);
	virtual void Exit(IPerson* entity);
	virtual bool OnMessage(IPerson* agent, const Telegram& msg);
	virtual CItems* RetrieveItemsAtLocation();
	virtual SItem* RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy);
	virtual CLocation** RequestDirectionsPossible(int&);
};

#endif